#pragma once
#include"init.h"
#include <QWidget>
#include "ui_game.h"

QT_BEGIN_NAMESPACE
namespace Ui { class gameClass; };
QT_END_NAMESPACE
class snake {
public:
	snake(QWidget *w, int x, int y, QImage image, int direction) :direction(direction) {
		this->label = new QLabel(w);
		label->setGeometry(x, y, frame_size, frame_size);
		label->setPixmap(QPixmap::fromImage(image));
		label->setScaledContents(1);
		label->show();
		li.push_back(this);
	}
	~snake() {
		delete label;
		snake::li.pop_front();
	}
	QLabel *label;
	short direction;
	static list<snake *>li;
};
//蛇的list存储是从蛇尾开始到蛇头
inline list<snake *>snake::li = {};
class game : public QWidget
{
	Q_OBJECT

public:
	game(QWidget *parent = nullptr);
	~game();
	QTimer *timer = new QTimer(this);
	void init(int tick, int size) {
		this->tick = tick;
		createSnake();
		timer->start(tick);
		show();
		this->size = size;
	}
private:
	Ui::gameClass *ui;
	int tick;
	int size;
	QLabel *food = nullptr;
	void createSnake() {
		for (int i = 0;i < 8;i++) {
			if (i == 0) {
				new snake(this, i * frame_size, 0, tailImage, head_right);
			}
			else if (i == 7) {
				new snake(this, i * frame_size, 0, headImage, head_right);
			}
			else {
				new snake(this, i * frame_size, 0, bodyImage, head_right);
			}
		}
	}
	void moving() {
		auto &head = *snake::li.rbegin();
		auto &tail = *snake::li.begin();
		head->label->setPixmap(QPixmap::fromImage(bodyImage));
		switch (head->direction) {
		case head_down:
			new snake(this, head->label->x(), head->label->y() + frame_size, headImage, head->direction);
			break;
		case head_up:
			new snake(this, head->label->x(), head->label->y() - frame_size, headImage, head->direction);
			break;
		case head_left:
			new snake(this, head->label->x() - frame_size, head->label->y(), headImage, head->direction);
			break;
		case head_right:
			new snake(this, head->label->x() + frame_size, head->label->y(), headImage, head->direction);
			break;
		}

		if (!food) {
			food = new QLabel(this);
			bool index = 1;
			while (index) {
				index = 0;
				food->setGeometry(size * QRandomGenerator::global()->bounded(0, frame_size), size * QRandomGenerator::global()->bounded(0, frame_size), frame_size, frame_size);
				for (auto it = snake::li.begin();it != snake::li.end();it++) {
					auto &itp = *it;
					if (itp->label->x() == food->x() && itp->label->y() == food->y()) {
						index = 1;
					}
				}
			}
			food->setPixmap(QPixmap::fromImage(foodImage));
			food->setScaledContents(1);
			food->show();
		}

		if (head->label->x() == food->x() && head->label->y() == food->y()) {
			delete food;
			food = nullptr;
		}
		else {
			delete tail;
			(*snake::li.begin())->label->setPixmap(QPixmap::fromImage(tailImage));
		}

		ui->speedLabel->setText(("当前刻度:" + to_string(tick)).c_str());
		ui->speedLabel->raise();

		if (head->label->x() < 0 || head->label->y() < 0 || head->label->x() >= width() || head->label->y() >= height()) {
			QMessageBox::information(this, "游戏失败", "哦豁，你撞墙了");
			this->close();
		}
		for (auto it = snake::li.begin();it != snake::li.end();it++) {
			auto &itp = *it;
			if (itp != head && head->label->x() == itp->label->x() && head->label->y() == itp->label->y()) {
				QMessageBox::information(this, "游戏失败", "哦豁，你吃到自己了");
				this->close();
			}
		}
	}
	void keyPressEvent(QKeyEvent *event) {
		auto &head = *snake::li.rbegin();
		if (event->key() == Qt::Key_A && (head->direction == head_up || head->direction == head_down)) {
			head->direction = head_left;
		}
		else if (event->key() == Qt::Key_D && (head->direction == head_up || head->direction == head_down)) {
			head->direction = head_right;
		}
		else if (event->key() == Qt::Key_S && (head->direction == head_right || head->direction == head_left)) {
			head->direction = head_down;
		}
		else if (event->key() == Qt::Key_W && (head->direction == head_right || head->direction == head_left)) {
			head->direction = head_up;
		}
		else if (event->key() == Qt::Key_A && head->direction == head_left) {
			QTimer::singleShot(0, this, &game::moving);
		}
		else if (event->key() == Qt::Key_D && head->direction == head_right) {
			QTimer::singleShot(0, this, &game::moving);
		}
		else if (event->key() == Qt::Key_S && head->direction == head_down) {
			QTimer::singleShot(0, this, &game::moving);
		}
		else if (event->key() == Qt::Key_W && head->direction == head_up) {
			QTimer::singleShot(0, this, &game::moving);
		}
		else if (event->key() == Qt::Key_Q) {
			tick += 10;
			if (tick > max_tick) {
				tick = max_tick;
			}
			timer->setInterval(tick);
			QTimer::singleShot(0, this, &game::moving);
		}
		else if (event->key() == Qt::Key_E) {
			tick -= 10;
			if (tick < 0) {
				tick = 0;
			}
			timer->setInterval(tick);
			QTimer::singleShot(0, this, &game::moving);
		}
	}
};
